# 加载当前目录下的模块
from . import QT5tool as qtt,JTool as jt,JToolCV2 as jcv
import pyautogui as mk

class lfzl:
    # lfzl的类
    gameName="Path of Exile"

    # 初始化类
    def __init__(self,gName=gameName):
        # 定义self对象属性
        self.gameName=gName
        # 窗口偏移量
        self.scpyxy=(16,39)
        # 窗口大小(1920,1080)
        self.widthHeight=(1920,1080)
        # 窗口大小_偏移(1936, 1119)(1920+16=1936,1080+39=1119)
        self.widthHeight_py=tuple(sum(pair) for pair in zip(self.widthHeight, self.scpyxy))
        # 窗口居中值(960,540)
        self.widthHeight_mid=tuple(int(pair/2) for pair in self.widthHeight)
        # 窗口居中值_偏移(968, 559)
        self.widthHeight_mid_py=tuple(int(pair/2) for pair in self.widthHeight_py)
        # 窗口左上角位置
        self.topLeft=(100,100)
        # 窗口地图区域点(1642-6,6,272-10,272-10)(131, 131)
        self.map_xywh=(1642-6,6,272-10,272-10)
        #  窗口地图中心点(131, 131)
        self.map_point_mid=tuple(int(n/2) for n in self.map_xywh[2:4])
        self.angle_=-90
        self.angle_temp=-91
        # 窗口中心点(1060, 640)s
        self.midPoit=tuple(sum(pair) for pair in zip(self.widthHeight_mid, self.topLeft))
        self.midPoit=tuple(n0-n1 for n0,n1 in zip(self.midPoit, self.scpyxy))
        # 获取游戏窗口标题的hWnd句柄=1248552="Path of Exile"
        self.hwnd=qtt.getTitle_hWnd(gName)
        # 创建窗口截图对象sC (1041, 1904, 3)
        self.sC=qtt.Qt5App(self.hwnd)
        # 标记是否按角度走默认为True
        self.angle_go=True





    def test(self):
        # 测试类方法
        print( "lfzl.gameName: ",lfzl.gameName)
        print( "self.gameName: ",self.gameName)
        print( "self.hwnd: ",self.hwnd)
        print("...")
        
        print( "self.scpyxy: ",self.scpyxy)
        print( "self.widthHeight: ",self.widthHeight)
        print( "self.widthHeight_py: ",self.widthHeight_py)
        print( "self.widthHeight_mid: ",self.widthHeight_mid)
        print( "self.widthHeight_mid_py: ",self.widthHeight_mid_py)
        print( "self.topLeft: ",self.topLeft)
        print( "self.map_xywh: ",self.map_xywh)
        print( "self.midPoit: ",self.midPoit)

    def getScMap(self):
        # 获取窗口的地图位置截图s
        return self.sC.read(self.map_xywh)
    
    def getScMap_wall(self,img=None):
        # 获取窗口的地图位置截图s(262, 262)单通道
        if img is None:
            iMap=self.sC.read(self.map_xywh)
        else:
            iMap=img
        # 返回地图和颜色选取的图
        self.iMap=iMap
        self.iMap_s=jcv.ps_sele_color(iMap)
        self.iMap_sdi=jcv.ps_dilate_ones(self.iMap_s,(3,3),iterations=10)
        return self.iMap,self.iMap_s,self.iMap_sdi

    """ angle_range_函数
        img,                    #绘制图(单/多通道)
        v_img,                  #v图(单通道)
        v_color=255             #v图的值
        angle=90,               #扫描角度
        center=(0,0),           #圆心点
        radius=20,              #半径
        r_color=(0,255,0),      #半径默认颜色,默认(绿色)
        s_range=(0,5),          #半径扫描区间
        s_show=False,           #是否显示扫描区
        s_color=(0,0,80),       #扫描区颜色,默认(暗红色)
        circle_show=False,      #是否显示绘制全圆
        circle_color=(0,20,20)  #默认(浅黄色)
        thicknes=1#全圆厚度
    """
    def angle_range_S(self,
                      img,
                      v_img,
                      angle=90,
                      center=(0,0),
                      radius=20,
                      s_range=(0,5),
                      r_color=(0,255,0),
                      r_color_r=(0,0,200),
                      v_color=255,
                      s_color=(0,0,80),
                      s_show=False,
                      circle_show=False,
                      circle_color=(0,80,80),
                      thicknes=1
                      ):
                    # sr,srr=s_range[:2]
                    # 扫描到墙的长度数
                    s_range_n=0
                    # 是否显示绘制全圆
                    if circle_show==True:
                        img=jcv.cv2.circle(img.copy(),center,radius,circle_color,thicknes)
                    # 扫描s_r区域
                    for i in range(s_range[0],s_range[1]+1):
                        angle_px=jt.math_angle2xy(angle,i,center)
                        # 区域是行列yx顺序
                        angle_px=jt.xy2yxL(angle_px,True)
                        # 判断是否显示扫描线
                        if s_show==True:
                            img[angle_px]=s_color
                        # 判断膨胀墙后的地图
                        if v_img[angle_px]==v_color:
                            s_range_n+=1
                            break
                    # 碰墙标色
                    angle_px=jt.math_angle2xy(angle,radius,center)
                    # 区域是行列yx顺序
                    angle_px=jt.xy2yxL(angle_px,True)
                    if s_range_n==0:
                        # 没有碰墙就默认色r_color
                        img[angle_px]=r_color
                    else:
                        # 有墙就标色r_color_r
                        img[angle_px]=r_color_r
                    self.iMap=img
                    print( 's_range_n:',s_range_n)
                    return img,s_range_n
            

    def getScMap_wall_dw(self,img=None):
        self.angle_temp%=360 
        
        # 获取窗口的地图位置截图s绘制向量
        if img is None:
            self.getScMap_wall()
        else:
           self.getScMap_wall(img)
        # 获取地图的宽高
        width_height=self.iMap.shape[:2]
        poit_mid=tuple(int(n/2) for n in width_height)
        center = poit_mid  # 圆心坐标
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp,center=center,radius=30,s_range=(0,30),circle_show=True,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+20,center=center,radius=30,s_range=(10,30),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+10,center=center,radius=30,s_range=(0,30),circle_show=False,s_show=True)

        # center_py=jt.sum2ab((50,150),(100,0),True)
        center_py=jt.sum2ab(center,(20,0),True)
        print(center_py)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp,center=center_py,radius=50,s_range=(0,50),circle_show=True,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+20,center=center_py,radius=50,s_range=(0,50),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+10,center=center_py,radius=50,s_range=(0,50),circle_show=False,s_show=True)
        
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp     ,center=center,radius=3,s_range=(2,2),circle_show=True,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45  ,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*2,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*3,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*4,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*5,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*6,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*7,center=center,radius=3,s_range=(2,2),circle_show=False,s_show=True)
        # a=self.angle_range_S(self.iMap, self.iMap_sdi,angle=self.angle_temp+45*8,center=center,radius=5,s_range=(0,8),circle_show=False,s_show=True)
        

        # # 获取窗口的地图位置截图s绘制向量
        # if img is None:
        #     self.getScMap_wall()
        # else:
        #    self.getScMap_wall(img)
        # # 获取地图的宽高
        # width_height=self.iMap.shape[:2]
        # poit_mid=tuple(int(n/2) for n in width_height)
        # center = poit_mid  # 圆心坐标
        # radius =20  # 半径
        # color = (0, 150, 150)  # 红色，BGR格式
        # thickness = 1  # 线条厚度
        # # 内圆区域
        # # self.iMap=jcv.cv2.circle(self.iMap.copy(), center, radius, color, thickness)
        # radius2 =35  # 半径
        # color2 = (0, 100, 100)  # 浅黄色，BGR格式
        # thickness2 = 1  # 线条厚度
        # # 外圆区域
        # self.iMap=jcv.cv2.circle(self.iMap.copy(), center, radius2, color2, thickness2)

        # #  开始前_暗黄色通行向量
        # for ii in range(10+3,radius2-1):
        #     # 黄色通行向量
        #     angle_px=jt.math_angle2xy(self.angle_temp,ii,center)
        #     self.iMap[angle_px]=(0,50,50)


        # # 外圆标记角度判断
        # sjd=int(20/2)
        # # 全部到墙里计数器
        # quan_180=0
        # # 左右段位正负计数器
        # jd=0


        # # 一段计算
        # # for i in range(self.angle_temp+sjd,self.angle_temp,-5):
        # # 一段 逆时针 A1点
        # i=self.angle_temp+90
        # ok=1
        # for ii in range(5,radius2):
        #     angle_px=jt.math_angle2xy(i,ii,center)
        #     self.iMap[angle_px]=(0,0,80)
        #     # 判断膨胀墙后的地图
        #     if self.iMap_sdi[angle_px]==255:
        #         ok=0
        #         break
        #     if ok==0:
        #         # 外圈到墙了
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
        #         jd-=15
        #         quan_180+=1
        #     else:
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)
        # # 一段 逆时针 A2点
        # i=self.angle_temp+10
        # ok=1
        # for ii in range(5,radius2):
        #     angle_px=jt.math_angle2xy(i,ii,center)
        #     self.iMap[angle_px]=(0,0,80)
        #     # 判断膨胀墙后的地图
        #     if self.iMap_sdi[angle_px]==255:
        #         ok=0
        #     if ok==0:
        #         # 外圈到墙了
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
        #         jd-=15
        #         quan_180+=1
        #     else:
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)
        # # 一段 逆时针 A3点
        # i=self.angle_temp+5
        # ok=1
        # for ii in range(5,radius2):
        #     angle_px=jt.math_angle2xy(i,ii,center)
        #     self.iMap[angle_px]=(0,0,80)
        #     # 判断膨胀墙后的地图
        #     if self.iMap_sdi[angle_px]==255:
        #         ok=0
        #     if ok==0:
        #         # 外圈到墙了
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
        #         jd-=15
        #         quan_180+=1
        #     else:
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)


        # # 默认正负角标记
        # jd_angle=None
        # # 二段计算
        # # for i in range(self.angle_temp,self.angle_temp-sjd,-5):
        # i=self.angle_temp
        # ok=1
        # for ii in range(5,radius2):
        #     angle_px=jt.math_angle2xy(i,ii,center)
        #     self.iMap[angle_px]=(0,0,80)
        #     # 判断膨胀墙后的地图
        #     if self.iMap_sdi[angle_px]==255:
        #         ok=0
        #         if i==self.angle_temp and jd_angle is None:
        #             jd_angle=1
        #         break
        # if ok==0:
        #     # 外圈到墙了
        #     self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
        #     jd+=10
        #     quan_180+=1
        # else:
        #     self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)
        # # 两段的左右正负角相加判断
        # # 判断默认角是否碰墙,才大幅度转弯
        # if jd_angle==1:
        #     self.angle_temp+=jd
        # # self.angle_temp+=10
        # # 启动一二段控制角度
        # self.angle_temp+=jd
        # # # 一直左扫摇头
        # # rand=jt.random.randint(5,15)
        # # self.angle_temp +=rand  
        # # 判断点数是否撞墙了
        # if quan_180>=4:
        #     rand=jt.random.randint(15,45)
        #     print( "rand: ",rand)
        #     self.angle_temp-=rand
        #     self.angle_go=False
        #     print(self.angle_go,":是否走位self.angle_go")

        # # 内圈------
        #  # 全部到墙里计数器
        # quan_180=0
        # # 内圆标记角度判断到墙
        # for i in range(self.angle_,self.angle_-360,-20):
        #     ok=1
        #     for ii in range(5,radius):
        #         angle_px=jt.math_angle2xy(i,ii,center)
        #         self.iMap[angle_px]=(0,0,128)
        #         # 判断膨胀墙后的地图
        #         if self.iMap_sdi[angle_px]==255:
        #             ok=0
        #             break
        #     if ok==0:
        #         self.iMap[jt.math_angle2xy(i,radius,center)]=(0, 0, 255)
        #         quan_180+=1
        #     else:
        #         self.iMap[jt.math_angle2xy(i,radius,center)]=(0, 255, 0)
        # # if quan_180>=2:
        # #     rand=jt.random.randint(5,15)
        # #     self.angle_temp-=rand
        # # if quan_180>=12:
        # #     rand=jt.random.randint(5,90)
        # #     self.angle_temp-=rand


        # # # 指针
        # # for i in range(10+3,radius2-1):
        # #   # 黄色通行向量
        # #     self.iMap[jt.math_angle2xy(self.angle_temp,i,center)]=(0, 200, 200)
        # for ii in range(10+3,radius2-1):
        #     # 黄色通行向量
        #     angle_px=jt.math_angle2xy(self.angle_temp,ii,center)
        #     self.iMap[angle_px]=(0,200,200)
        
        # # for i in range(5,radius-1):
        # #     # 绿色通行向量
        # #     self.iMap[jt.math_angle2xy(self.angle_,i,center)]=(0, 255, 0)
        # for ii in range(5,radius-1):
        #     # 绿色通行向量
        #     angle_px=jt.math_angle2xy(self.angle_,ii,center)
        #     self.iMap[angle_px]=(0,255,0)
        
        return self.iMap,self.iMap_s,self.iMap_sdi

            
# 半成品JianPF2024.9.23x17:22
    def getScMap_wall_dw_001(self,img=None):
        # 获取窗口的地图位置截图s绘制向量
        if img is None:
            self.getScMap_wall()
        else:
           self.getScMap_wall(img)
        # 获取地图的宽高
        width_height=self.iMap.shape[:2]
        poit_mid=tuple(int(n/2) for n in width_height)
        center = poit_mid  # 圆心坐标
        radius =10  # 半径
        color = (0, 150, 150)  # 红色，BGR格式
        thickness = 1  # 线条厚度
        # 内圆区域
        # self.iMap=jcv.cv2.circle(self.iMap.copy(), center, radius, color, thickness)
        radius2 =35  # 半径
        color2 = (0, 100, 100)  # 浅黄色，BGR格式
        thickness2 = 1  # 线条厚度
        # 外圆区域
        self.iMap=jcv.cv2.circle(self.iMap.copy(), center, radius2, color2, thickness2)
        
        # # 外圆标记角度判断
        # for i in range(self.angle_,self.angle_-360,-10):
        #     ok=1
        #     for ii in range(5,radius2):
        #         angle_px=jt.math_angle2xy(i,ii,center)
        #         self.iMap[angle_px]=(0,0,80)
        #         # 判断膨胀墙后的地图
        #         if self.iMap_sdi[angle_px]==255:
        #             ok=0
        #             break
        #     if ok==0:
        #         # 外圈到墙了
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
        #     else:
        #         self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)

        # 外圆标记角度判断
        sjd=int(20/2)
        # 全部到墙里计数器
        quan_180=0
        # 左右段位正负计数器
        jd=0
        # 一段计算
        for i in range(self.angle_temp+sjd,self.angle_temp,-5):
            ok=1
            for ii in range(5,radius2):
                angle_px=jt.math_angle2xy(i,ii,center)
                self.iMap[angle_px]=(0,0,80)
                # 判断膨胀墙后的地图
                if self.iMap_sdi[angle_px]==255:
                    ok=0
                    break
            if ok==0:
                # 外圈到墙了
                self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
                jd-=10
                quan_180+=1
            else:
                self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)
        # 默认正负角标记
        jd_angle=None
        # 二段计算
        for i in range(self.angle_temp,self.angle_temp-sjd,-5):
            ok=1
            for ii in range(5,radius2):
                angle_px=jt.math_angle2xy(i,ii,center)
                self.iMap[angle_px]=(0,0,80)
                # 判断膨胀墙后的地图
                if self.iMap_sdi[angle_px]==255:
                    ok=0
                    if i==self.angle_temp and jd_angle is None:
                        jd_angle=1
                    break
            if ok==0:
                # 外圈到墙了
                self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 0, 255)
                jd+=10
                quan_180+=1
            else:
                self.iMap[jt.math_angle2xy(i,radius2,center)]=(0, 255, 0)
        # 两段的左右正负角相加判断
        # 判断默认角是否碰墙,才大幅度转弯
        if jd_angle==1:
            self.angle_temp+=jd
        # 判断点数是否撞墙了
        if quan_180>=4:
            rand=jt.random.randint(5,45)
            print( "rand: ",rand)
            self.angle_temp-=rand
        # 一直左扫摇头
        rand=jt.random.randint(5,15)
        self.angle_temp +=rand  


        # 内圈------
         # 全部到墙里计数器
        quan_180=0
        # 内圆标记角度判断到墙
        for i in range(self.angle_,self.angle_-360,-20):
            ok=1
            for ii in range(5,radius):
                angle_px=jt.math_angle2xy(i,ii,center)
                self.iMap[angle_px]=(0,0,128)
                # 判断膨胀墙后的地图
                if self.iMap_sdi[angle_px]==255:
                    ok=0
                    break
            if ok==0:
                self.iMap[jt.math_angle2xy(i,radius,center)]=(0, 0, 255)
                quan_180+=1
            else:
                self.iMap[jt.math_angle2xy(i,radius,center)]=(0, 255, 0)
        if quan_180>=2:
            rand=jt.random.randint(5,15)
            self.angle_temp-=rand
        if quan_180>=12:
            rand=jt.random.randint(5,90)
            self.angle_temp-=rand


        # # 指针
        # for i in range(10+3,radius2-1):
        #   # 黄色通行向量
        #     self.iMap[jt.math_angle2xy(self.angle_temp,i,center)]=(0, 200, 200)
        for ii in range(10+3,radius2-1):
            # 黄色通行向量
            angle_px=jt.math_angle2xy(self.angle_temp,ii,center)
            self.iMap[angle_px]=(0,200,200)
        
        # for i in range(5,radius-1):
        #     # 绿色通行向量
        #     self.iMap[jt.math_angle2xy(self.angle_,i,center)]=(0, 255, 0)
        for ii in range(5,radius-1):
            # 绿色通行向量
            angle_px=jt.math_angle2xy(self.angle_,ii,center)
            self.iMap[angle_px]=(0,255,0)
        
        return self.iMap,self.iMap_s,self.iMap_sdi
    
    def setScTopLeftWidthHeight(self):
        # 设置窗口的位置和宽高
        scx,scy=self.topLeft[0],self.topLeft[1]
        width,height=self.widthHeight[0],self.widthHeight[1]
        self.sC.winMoveTo(scx,scy)
        self.sC.winResizeTo(width,height)
        self.sC.win_action()
    def mov_mid(self):
        # 鼠标控制人移动到中心
        pyxy=self.midPoit
        mk.click(pyxy)
        print( 'movC_x,y: ',pyxy)
    def mov_go(self,point):
        # 鼠标控制人移动到正负位置
        pyxy=tuple(sum(pair) for pair in zip(self.midPoit, point))
        mk.click(pyxy,duration=0.5)
        print( 'movC_xx,y: ',pyxy)
    def mov_go_angle(self,angle_goClick=True):
        # 鼠标控制人移动到正负位置
        # 是否按角度走位
        angle_goClick=angle_goClick & self.angle_go  
        # 开始按角度走位
        if angle_goClick:
            # 鼠标控制人移动到正负位置
            point=jt.math_angle2xy(self.angle_temp,80)#150 70
            point=jt.xy2yxL(point,True)
            pyxy=tuple(sum(pair) for pair in zip(self.midPoit, point))
            mk.click(pyxy)
            # print( 'point: ',point)
            # print( 'pyxy: ',pyxy)
        # 默认按标志走 
        self.angle_go=True





# # 热键模块暂停模块JianPF2024.9.25V01

# from pynput.keyboard import GlobalHotKeys
# import threading
# import time

# hkey="ok"
# # 简单的设置退出快捷键shift+F4的标注模板
# def shift_esc():
#     global hkey
#     print("shift_esc运行结束...")
#     # 通知外部要退出
#     hkey="exit"
#     # 退出监听和进程
#     exit()
# # 设置暂停10
# def shift_F5():
#     global hkey
#     print("shift_F5暂停运行10秒")
#     # 通知外部要暂停操作
#     hkey="stop"
#     # time.sleep(10)
#     # print("暂停运行10结束...")

# def ctrl_up():
#     global hkey
#     hkey="up"
#     # print("ctrl_up...")
# def ctrl_down():
#     global hkey
#     hkey="down"
#     # print("ctrl_down...")

# # 热键的进程函数
# def thread_hkey_listener(stop_event):
#     # with包裹执行代码块
#     with GlobalHotKeys({'<shift>+<F4>':shift_esc,
#                         '<shift>+<F5>':shift_F5,
#                         '<ctrl>+<up>': ctrl_up,
#                         '<ctrl>+<down>': ctrl_down,
#                         }) as thkey: 
#                 print("join...")
#                 # 包裹内while循环判断没有stop_event.set()=True进程标识
#                 # 或者直接while标识hkey = "exit"也是可以的
#                 while not stop_event.is_set() and hkey != "exit":
#                     thkey.join(1)  # 每隔1秒检查一次
#                 # 手动设置了stop_event.set() 或 hkey = "exit" 
#                 print("with GlobalHotKeys线程结束") 
#                 # 进程执行完就自动销毁了

# # 创建两个线程的停止事件,对应进程标识,进程结束后直接删除内存(无法重启)
# stop_event=threading.Event()
# # stop_event2=threading.Event()
# # 创建进程
# thread_hkey=threading.Thread(target=thread_hkey_listener,args=(stop_event,))
# # thread_hkey2=threading.Thread(target=thread_hkey_listener,args=(stop_event2,))
# # 进程启动
# thread_hkey.start() 
# # thread_hkey2.start() 
# #
# # 在某个时刻，如果你想手动停止线程，可以调用 或 hkey = "exit" 
# stop_event.set()
# # stop_event2.set()
